from fastapi import APIRouter, Body, Depends, Path

from common.pkg.fastapi_util import cbv
from common.route.route import ZipCustomerRoute
from common.route.tenant_route import TenantBaseAPIRoute
from common.route.user_route import TenantMustLoginAPIRoute
from common.utils.depends.common import (
    get_current_tenant, Page, get_page_info
)
from common.utils.depends.tips_depends import get_auth_code
from common.utils.resp import JsonResponse, RC
from core.view import TenantBaseView
from schema.req_schema.tenant_req_schema import RegisterTenantModel, UpdateTenantModel
from service.tenant_service import TenantService, TenantUserService, TenantPayWayService, TenantMallService

router = APIRouter(prefix="/tenant",
                   tags=["tenant"],
                   route_class=TenantMustLoginAPIRoute)

tenant_base_router = APIRouter(prefix="/tenant",
                               tags=["tenant"],
                               route_class=ZipCustomerRoute(TenantBaseAPIRoute, TenantMustLoginAPIRoute))


@cbv(router)
class NoChoiceTenantView(TenantBaseView):
    @router.post("/register", description="注册新的租户,等审核通过之后就可以使用了")
    async def register_new_tenant(self, tenant: RegisterTenantModel = Body(...)):
        # 同一个用户3s内只能注册一次
        can = await self.redis.set(f"tenant:register:{self.user_id}", self.user_id, nx=True, ex=3)
        if not can:
            return JsonResponse(code=RC.RATE_LIMIT, msg="请求太快,请稍后再试!").to_response()
        ts = TenantService(self.mgw, self.redis)
        ok, data_or_code = await ts.add_new_tenant(self.user_id, tenant)
        return self.unpack_response(ok, data_or_code)


@cbv(tenant_base_router)
class ChoiceTenantView(TenantBaseView):

    @tenant_base_router.get("/current",
                            description="用户登陆之后,选择租户进入系统之后,通过这个接口可以获取当前选择的租户的信息",
                            dependencies=[Depends(get_auth_code)])
    async def get_current_tenant_info(self,
                                      tenant_info: dict = Depends(get_current_tenant)
                                      ):
        # 判断当前用户是否属于当前租户 存在过期的问题，所以需要检查一下
        exist = await self.redis.sismember(f"tenant:{self.tenant_id}:user:set", self.user_id)
        if not exist:
            return JsonResponse(code=RC.NEED_RELOGIN_TENANT, msg="凭证过期,需要重新选择租户登陆")
        return JsonResponse(data=tenant_info).to_response()

    @tenant_base_router.put("/current",
                            description="更新当前租户的信息,需要当前用户是租户的拥有者",
                            dependencies=[Depends(get_auth_code)])
    async def update_current_tenant_info(self,
                                         tenant_info: dict = Depends(get_current_tenant),
                                         update_model: UpdateTenantModel = Body(...)
                                         ):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以修改信息")

        ts = TenantService(self.mgw, self.redis)
        ok, data_or_code = await ts.update_tenant_info(self.tenant_id, old_version=tenant_info.get("version"),
                                                       tenant_model=update_model)
        return self.unpack_response(ok, data_or_code)

    # ======== tenant 用户相关 =================
    @tenant_base_router.post("/users", description="给租户添加人员,需要当前用户是租户的拥有者")
    async def add_users_to_tenant(self,
                                  email: str = Body(..., embed=True),
                                  tenant_info: dict = Depends(get_current_tenant),
                                  ):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        # 判断是否可以修改 后面应该改成权限认证
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以添加用户")

        tus = TenantUserService(self.mgw, self.redis)
        ok, data_or_code = await tus.bind_tenant_and_user_by_email(self.tenant_id, email)
        return self.unpack_response(ok, data_or_code)

    @tenant_base_router.delete("/users", description="给租户移除人员,需要当前用户是租户的拥有者")
    async def remove_users_from_tenant(self,
                                       remove_user_id: int = Body(..., embed=True),
                                       tenant_info: dict = Depends(get_current_tenant)
                                       ):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        # 判断是否可以删除 后面应该改成权限认证
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以删除用户")

        if remove_user_id == self.user_id or remove_user_id == tenant_info.get("owner_id"):
            return JsonResponse(code=RC.FORBIDDING, msg="不可以移除自己/超级管理员")
        tus = TenantUserService(self.mgw, self.redis)
        ok, data_or_code = await tus.remove_user_from_tenant(self.tenant_id, remove_user_id)
        return self.unpack_response(ok, data_or_code)

    @tenant_base_router.get("/users", description="获取当前租户下面的人员信息")
    async def get_users_in_tenant(self,
                                  page_info: Page = Depends(get_page_info),
                                  tenant_info: dict = Depends(get_current_tenant),
                                  ):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        # 判断是否可以查看 后面应该改成权限认证
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以删除用户")
        tenant_id = tenant_info.get("tenant_id")

        tus = TenantUserService(self.mgw, self.redis)
        ok, data_or_code = await tus.get_users_info(tenant_id, page_info)
        return self.unpack_response(ok, data_or_code)

    @tenant_base_router.get("/mall", description="获取当前租户下面的mall")
    async def get_mall_list(self):
        tms = TenantMallService(self.mgw, self.redis)
        ok, data_or_none = await tms.get_mall_list(self.tenant_id)
        return self.unpack_response(ok, data_or_none)

    # =========tenant 支付方式相关 ==================
    @tenant_base_router.get("/pay_way", description="获取当前租户下面所有的支持的支付类型")
    async def get_tenant_all_pay_way(self, tenant_info: dict = Depends(get_current_tenant)):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        tenant_id = tenant_info.get("tenant_id")
        tpws = TenantPayWayService(self.mgw, self.redis)
        ok, data_or_code = await tpws.get_pay_way_list(tenant_id)
        return self.unpack_response(ok, data_or_code)

    @tenant_base_router.post("/pay_way",
                             description="当前租户申请使用某一个支付方式,当前忽略审核步骤，理论上来说，申请之后，需要审核通过之后才可以用， 现在就直接用")
    async def tenant_apply_to_use_pay_way(self,
                                          pay_way_id: int = Body(..., embed=True),
                                          tenant_info: dict = Depends(get_current_tenant),
                                          ):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以修改")

        tpws = TenantPayWayService(self.mgw, self.redis)
        ok, data_or_code = await tpws.add_pay_way(self.tenant_id, pay_way_id)
        return self.unpack_response(ok, data_or_code)

    @tenant_base_router.put("/pay_way/{pay_way_id:int}", description="在当前租户启用或者禁用某一个支付方式")
    async def enable_or_disable_pay_way_for_tenant(self,
                                                   pay_way_id: int = Path(...),
                                                   enable: bool = Body(..., embed=True),
                                                   tenant_info: dict = Depends(get_current_tenant),
                                                   ):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以修改")
        tpws = TenantPayWayService(self.mgw, self.redis)
        ok, data_or_code = await tpws.enable_or_disable_pay_way(self.tenant_id, pay_way_id, enable)
        return self.unpack_response(ok, data_or_code)

    @tenant_base_router.delete("/pay_way/{pay_way_id:int}", description="当前租户删除某个支付方式的使用")
    async def delete_pay_way_from_tenant(self,
                                         pay_way_id: int = Path(...),
                                         tenant_info: dict = Depends(get_current_tenant),
                                         ):
        if tenant_info is None:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除")
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以修改")
        tpws = TenantPayWayService(self.mgw, self.redis)
        ok, data_or_code = await tpws.delete_pay_way(self.tenant_id, pay_way_id)
        return self.unpack_response(ok, data_or_code)
